package br.ufpe.cin.ip.biblioteca.repositorios;

import br.ufpe.cin.ip.biblioteca.entidades.Livro;
import br.ufpe.cin.ip.biblioteca.entidades.Publicacao;
import br.ufpe.cin.ip.biblioteca.entidades.Revista;
import br.ufpe.cin.ip.biblioteca.excecoes.PublicacaoJaCadastradaException;
import br.ufpe.cin.ip.biblioteca.excecoes.PublicacaoNaoEncontradaException;
import br.ufpe.cin.ip.biblioteca.excecoes.RepositorioException;
import br.ufpe.cin.ip.biblioteca.iterator.IteratorPublicacao;
import br.ufpe.cin.ip.biblioteca.iterator.IteratorPublicacaoLista;
import br.ufpe.cin.ip.biblioteca.tad.ListaPublicacao;

public class RepositorioPublicacaoLista implements RepositorioPublicacao {
	private ListaPublicacao publicacoes;
	private int indice;
	
	public RepositorioPublicacaoLista() {
		super();
		this.indice = 0;
	}
	
	@Override
	public void adicionar(Publicacao publicacao) throws RepositorioException, PublicacaoJaCadastradaException {
		publicacao.setId(this.indice + 1);
		
		if(this.publicacoes!=null) {
			if(this.existe(publicacao)) {
				throw new PublicacaoJaCadastradaException();
			} else {
				this.publicacoes.inserir(publicacao);
				this.indice++;
			}
		} else {
			this.publicacoes = new ListaPublicacao(publicacao);
			this.indice++;
		}
	}
	
	@Override
	public void remover(Publicacao publicacao) throws RepositorioException, PublicacaoNaoEncontradaException {
		if(this.existe(publicacao)) {
			this.publicacoes.remover(publicacao);
		} else {
			throw new PublicacaoNaoEncontradaException();
		}
	}
	
	@Override
	public void atualizar(Publicacao publicacao) throws RepositorioException, PublicacaoNaoEncontradaException {
		if(this.publicacoes!=null) {
			Publicacao retorno = null;
			IteratorPublicacao it = this.publicacoes.getIterator();
			
			while(it.hasNext()) {
				Publicacao p = it.next();
				
				if(publicacao.equals(p))
					retorno = p;
			}
			
			if(retorno==null) {
				throw new PublicacaoNaoEncontradaException();
			} else {
				retorno.setTitulo(publicacao.getTitulo());
				retorno.setLocal(publicacao.getLocal());
				retorno.setMatriculaUsuarioEmprestimo(publicacao.getMatriculaUsuarioEmprestimo());
				
				if(retorno instanceof Livro && publicacao instanceof Livro) {
					Livro publicacaoLivro = (Livro) publicacao;
					Livro retornoLivro = (Livro) retorno;
					
					retornoLivro.setEdicao(publicacaoLivro.getEdicao());
					retornoLivro.setEditora(publicacaoLivro.getEditora());
					retornoLivro.setAnoEdicao(publicacaoLivro.getAnoEdicao());
					retornoLivro.setAnoPublicacao(publicacaoLivro.getAnoPublicacao());
				} else if(retorno instanceof Revista && publicacao instanceof Revista) {
					Revista publicacaoRevista = (Revista) publicacao;
					Revista retornoRevista = (Revista) retorno;
					
					retornoRevista.setVolume(publicacaoRevista.getVolume());
					retornoRevista.setFasciculo(publicacaoRevista.getFasciculo());
					retornoRevista.setNumero(publicacaoRevista.getNumero());
					retornoRevista.setAno(publicacaoRevista.getAno());
				}
			}
		} else {
			throw new PublicacaoNaoEncontradaException();
		}
	}
	
	@Override
	public Publicacao buscar(Publicacao publicacao) throws RepositorioException, PublicacaoNaoEncontradaException {
		if(this.publicacoes!=null) {
			Publicacao retorno = null;
			IteratorPublicacao it = this.publicacoes.getIterator();
			
			while(it.hasNext()) {
				Publicacao p = it.next();
				
				if(publicacao.equals(p))
					retorno = p;
			}
			
			if(retorno==null) {
				throw new PublicacaoNaoEncontradaException();
			} else {
				return retorno;
			}
		} else {
			throw new PublicacaoNaoEncontradaException();
		}
	}
	
	@Override
	public IteratorPublicacao getIterator() {
		return new IteratorPublicacaoLista(this.publicacoes);
	}
	
	@Override
	public boolean existe(Publicacao publicacao) throws RepositorioException {
		boolean retorno = false;
		
		if(this.publicacoes!=null) {
			IteratorPublicacao it = this.publicacoes.getIterator();
			
			while(it.hasNext()) {
				Publicacao p = it.next();
				
				if(publicacao.equals(p))
					retorno = true;
			}
		}
		
		return retorno;
	}
}
